﻿using System;
using System.Collections.Generic;
using Sinacor.Infra.UI.Common;
using Sinacor.Infra.UI.Security.Services;
using Sinacor.UI.Application.Menu.Communication.Infra.Authorization.Menu;
using PSE.Framework.Common.Security.Services.Configuration;

namespace Sinacor.UI.Application.Menu.Communication
{
    public class Menu : BaseCommunication
    {
        public Menu(SessionInformation session) : base(session)
        {

        }

        public List<Model.Company> RetrieveCompanies()
        {
            List<Model.Company> retorno = new List<Model.Company>();
            IMenu service = null;

            try
            {
                using (ServiceInstance<IMenu> serviceInstance = new ServiceInstance<IMenu>())
                {
                    service = serviceInstance.TryGetInstance(this.Session,CriptographyLevelType.Basic);

                    List<CompanyResponse> companyResponse = service.RetrieveCompanies();

                    foreach (CompanyResponse company in companyResponse)
                    {
                        Model.Company companyModel = new Model.Company();
                        companyModel.Id = company.Id;
                        companyModel.Name = company.Name;
                        companyModel.CGC = company.CGC;
                        companyModel.DbInstance = company.DbInstance;
                        companyModel.DbUser = company.DbUser;
                        retorno.Add(companyModel);
                    }
                }
            }
            catch (Exception ex)
            {
                HandleFault(ex);
            }

            return retorno;
        }

		public List<Model.Module> RetrieveModules(int companyId)
		{
			List<Model.Module> retorno = new List<Model.Module>();
			IMenu service = null;

			try
			{
				using (ServiceInstance<IMenu> serviceInstance = new ServiceInstance<IMenu>())
				{
                    service = serviceInstance.TryGetInstance(this.Session, CriptographyLevelType.Basic);

					List<ModuleResponse> moduleResponse = service.RetrieveModules(companyId);

					foreach (ModuleResponse module in moduleResponse)
					{
						Model.Module moduleModel = new Model.Module();
						moduleModel.Id = module.Id;
						moduleModel.Name = module.Name;
						moduleModel.Items = CastSubMenuItens(module.Items);
						moduleModel.Roles = CastRoleItens(module.Roles);
						retorno.Add(moduleModel);
					}
				}
			}
			catch (Exception ex)
			{
				HandleFault(ex);
			}

			return retorno;
		}

		public bool CheckRolePermission(string role, string moduleId, int companyId)
		{
			bool retorno = false;
			IMenu service = null;

			try
			{
				using (ServiceInstance<IMenu> serviceInstance = new ServiceInstance<IMenu>())
				{
                    service = serviceInstance.TryGetInstance(this.Session, CriptographyLevelType.Basic);
					retorno = service.CheckRolePermission(role, moduleId, companyId);
				}
			}
			catch (Exception ex)
			{
				HandleFault(ex);
			}

			return retorno;
		}

        List<Model.MenuItem> CastSubMenuItens(List<MenuItemResponse> response)
        {
            List<Model.MenuItem> menuItens = new List<Model.MenuItem>();

            if (response != null)
            {
                foreach (MenuItemResponse itemResponse in response)
                {
                    Model.MenuItem item = new Model.MenuItem();
                    item.Assembly = itemResponse.Assembly;
                    item.Classe = itemResponse.Classe;
                    item.Id = itemResponse.Id;
                    item.Name = itemResponse.Name;
                    item.Role = itemResponse.Role;

                    if (itemResponse.Children != null && itemResponse.Children.Count > 0)
                        item.Children = CastSubMenuItens(itemResponse.Children);

                    menuItens.Add(item);
                }
            }

            return menuItens;
        }

        List<Model.Role> CastRoleItens(List<RoleResponse> response)
        {
            List<Model.Role> roles = new List<Model.Role>();

            if (response != null)
            {
                foreach (RoleResponse roleResponse in response)
                {
                    Model.Role item = new Model.Role();
                    item.Name = roleResponse.Name;

                    roles.Add(item);
                }
            }

            return roles;
        }
    }
}